package org.jsola.hr.common;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.jsola.hr.dto.AttendAdvancedDTO;
import org.jsola.hr.dto.attendrule.AttendRulePunchTimeAddDTO;
import org.jsola.hr.dto.attendrule.NonWorkDayRuleDTO;
import org.jsola.hr.dto.attendrule.WorkDayRuleDTO;
import org.jsola.hr.dto.attendschedule.AttendPeriodDTO;
import org.jsola.hr.entity.AttendPunchTimeDO;
import org.jsola.hr.exception.HrException;

import java.text.ParseException;
import java.util.Date;
import java.util.List;

/**
 * 考勤工具类
 *
 * @author wxz
 */
public class AttendKit {

    /**
     * 上班是否迟到
     *
     * @param punchTime 上班打卡时间
     * @param onWorkTime 上班时间
     * @param advanced 高级设置
     * @param yesterday 昨日下班晚走(分钟)
     * @return 迟到的分钟数
     */
    public static int isLateOnWork(Date punchTime, Date onWorkTime, AttendAdvancedDTO advanced, int yesterday) {

        // 允许迟到早退 ; 1-允许,0-不允许
        int isAllowedLateEarly = advanced.getIsAllowedLateEarly();
        // 上班允许迟到(分钟)
        int lateMinute = advanced.getLateMinute();
        // 允许晚走晚到 ; 1-允许,0-不允许
        int isAllowLateLate = advanced.getIsAllowLateLate();
        // 上班晚到(分钟)
        int onWorkLateMinute = advanced.getOnWorkLateMinute();
        // 下班晚走(分钟)
        int offWorkLateMinute = advanced.getOffWorkLateMinute();

        // 上班打卡时间-毫秒
        long punchMillis = punchTime.getTime();
        // 上班时间-毫秒
        long onWorkMillis = onWorkTime.getTime();
        // 迟到了几分钟
        int late = (int) ((punchMillis - onWorkMillis) / (1000 * 60));
        if (late <= 0) {
            return 0;
        }

        // 允许迟到早退、允许晚走晚到
        if (isAllowedLateEarly == 1 && isAllowLateLate == 1) {
            if (late <= lateMinute || (late <= onWorkLateMinute && offWorkLateMinute >= yesterday)) {
                return 0;
            }
            else {
                late = late - onWorkLateMinute;
            }
        }
        // 允许迟到早退、不允许晚走晚到
        else if (isAllowedLateEarly == 1 && isAllowLateLate == 0) {
            if (late <= lateMinute) {
                return 0;
            }
            else {
                late = late - lateMinute;
            }
        }
        // 不允许迟到早退、允许晚走晚到
        else if (isAllowedLateEarly == 0  && isAllowLateLate == 1) {
            if (late <= onWorkLateMinute && offWorkLateMinute >= yesterday) {
                return 0;
            }
            else {
                late = late - onWorkLateMinute;
            }
        }

        return late;
    }

    /**
     * 下班是否早退
     *
     * @param punchTime 下班打卡时间
     * @param offWorkTime 下班时间
     * @param isAllowedLateEarly 允许迟到早退 ; 1-允许,0-不允许
     * @param earlyMinute 下班允许早退(分钟)
     * @return 早退的分钟数
     */
    public static int isEarlyOffWork(Date punchTime, Date offWorkTime, int isAllowedLateEarly, int earlyMinute) {

        // 下班打卡时间-毫秒
        long punchMillis = punchTime.getTime();
        // 下班时间-毫秒
        long onWorkMillis = offWorkTime.getTime();
        // 早退了几分钟
        int late = (int) ((onWorkMillis - punchMillis) / (1000 * 60));
        if (late <= 0) {
            return 0;
        }

        // 允许迟到早退
        if (isAllowedLateEarly == 1) {
            if (late <= earlyMinute) {
                return 0;
            }
            else {
                late = late - earlyMinute;
            }
        }

        return late;
    }

    /**
     *  打卡时间限制 xxx(时间点)可打上班的卡,xxx(时间点) 可打下班卡
     *
     * @param workStatus 工作状态;1-上班打卡,2-下班打卡
     * @param workTime 上班时间或下班时间(HH:mm)
     * @param minutes 距离相差分钟数
     * @return 是否可以打卡;1-可以,0-不可以
     * @throws ParseException
     */
    public static Boolean checkTimeLimit(int workStatus, String workTime, String minutes, String attendDateStr) {

        // 是否可以打卡;1-可以,0-不可以
        int isPunch = 1;
        boolean flag = true;

        Date workDate = null;
        try {
            workDate = DateUtils.parseDate(attendDateStr + " " + workTime, "yyyy-MM-dd HH:mm");
        } catch (ParseException e) {
            e.printStackTrace();
        }

        // 如果是上班 1-上班打卡,2-下班打卡,3-今日完成打卡
        if (workStatus == 1) {
            // 获取距离上班允许打卡的时间点
            Date allowPunchDate = HrKit.addMinutes(workDate, -(Integer.valueOf(minutes).intValue()));
            if (workDate.getTime() < allowPunchDate.getTime()) {
                flag = false;
            }
        }
        // 如果是下班 1-上班打卡,2-下班打卡,3-今日完成打卡
        if (workStatus == 2) {
            // 获取下班之后,允许打下班的卡的时间
            Date allowPunchDate = HrKit.addMinutes(workDate, (Integer.valueOf(minutes).intValue()));
            if (allowPunchDate.getTime() < workDate.getTime()) {
                flag = false;
            }
        }

        return flag;
    }

    /**
     * 校验打卡时间段
     *
     * @param periodList
     */
    public static void validAttendPeriod(List<AttendPeriodDTO> periodList) {

        for (int i = 0; i < periodList.size(); i++) {

            String startPeriod = periodList.get(i).getStartPeriod();
            String endPeriod = periodList.get(i).getEndPeriod();
            // 应晚于上班时间
            int startInt = Integer.valueOf(startPeriod.replace(":", "")).intValue();
            int endInt = Integer.valueOf(endPeriod.replace(":", "")).intValue();
            if (endInt == startInt) {
                throw new HrException("应晚于上班时间");
            }

            //
            if (i  > 0) {

                int pre = i - 1;
                String preEndPeriod = periodList.get(pre).getEndPeriod();
                int preEndInt = Integer.valueOf(preEndPeriod.replace(":", "")).intValue();

                if (preEndInt >= startInt || preEndInt >= endInt) {
                    throw new HrException("应晚于上段下班时间");
                }
            }

        }
    }

    /**
     * 初始化工作日加班
     *
     * @param workDayRuleDTO
     * @return
     */
    public static WorkDayRuleDTO initWorkDayRule(WorkDayRuleDTO workDayRuleDTO) {

        if (workDayRuleDTO == null) {
            workDayRuleDTO = new WorkDayRuleDTO();
            // 是否允许工作日加班;true-是,false-否
            workDayRuleDTO.setIsWorkDay(false);
            // 加班开始时间： 下班后 x 分钟开始计算加班
            workDayRuleDTO.setStartMinutes(0);
            // 最短加班时长：30 分钟 不足30分钟记录为未加班
            workDayRuleDTO.setShortMinutes(0);
            // 最长加班时长：4 分钟 超过则记录为4分钟
            workDayRuleDTO.setLongestMinutes(0);
        }
        else {
            if (workDayRuleDTO.getIsWorkDay() == null) {
                workDayRuleDTO.setIsWorkDay(false);
            }
            if (workDayRuleDTO.getStartMinutes() == null) {
                workDayRuleDTO.setStartMinutes(0);
            }
            if (workDayRuleDTO.getShortMinutes() == null) {
                workDayRuleDTO.setShortMinutes(0);
            }
            if (workDayRuleDTO.getLongestMinutes() == null) {
                workDayRuleDTO.setLongestMinutes(0);
            }
        }

        return workDayRuleDTO;
    }

    /**
     * 初始化非工作日加班
     *
     * @param nonWorkDayRuleDTO
     * @return
     */
    public static NonWorkDayRuleDTO initNonWorkDayRule(NonWorkDayRuleDTO nonWorkDayRuleDTO) {

        if (nonWorkDayRuleDTO == null) {
            nonWorkDayRuleDTO = new NonWorkDayRuleDTO();
            // 是否允许非工作日加班;true-允许,false-不允许
            nonWorkDayRuleDTO.setIsNonWorkDay(false);
            // 最短加班时长：30 分钟 不足30分钟记录为未加班
            nonWorkDayRuleDTO.setShortMinutes(0);
            // 最长加班时长：4 分钟 超过则记录为4分钟
            nonWorkDayRuleDTO.setLongestMinutes(0);
        }
        else {
            if (nonWorkDayRuleDTO.getIsNonWorkDay() == null) {
                nonWorkDayRuleDTO.setIsNonWorkDay(false);
            }
            if (nonWorkDayRuleDTO.getShortMinutes() == null) {
                nonWorkDayRuleDTO.setShortMinutes(0);
            }
            if (nonWorkDayRuleDTO.getLongestMinutes() == null) {
                nonWorkDayRuleDTO.setLongestMinutes(0);
            }
        }

        return nonWorkDayRuleDTO;
    }

}
